﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SubirInformacion
{
    public class Procesar
    {
        Guid operacionPrestamo = new Guid("1C6F54A2-AB24-45AA-BD1C-55E06F26F05E");
        Guid operacionDevolucion = new Guid("1D13C26B-6185-4656-8BDA-A55CFC2EA1D0");
        Guid usuario = new Guid("BDBB26DA-F9DE-49E2-84B3-B16D944C61C8");
        string Activo = "ACT";
        string Competado = "COM";

        public int totalRegistrosProcesar { get; set; }
        public int totalRegistrosProcesados { get; set; }

        public Procesar()
        {
            using (var contexto = new ContextoBiciq())
            {
                totalRegistrosProcesar = contexto.OperacionesEstacion.Count();
            }
        }

        public Resultado ProcesarInformacion()
        {
          
            Resultado resultado = new Resultado();
            using (var contexto = new ContextoBiciq())
            {
                var estaciones = contexto.Estacion;
                Operacion prestamo = null;


                #region Prestamo
                System.Diagnostics.Trace.WriteLine("Empezando Préstamos.....");
                foreach (var operacion in contexto.OperacionesEstacion.Where(o => o.operacion == "prestamo").OrderBy(o => o.Fecha))
                {
                    var fecha = operacion.Fecha = new DateTime(operacion.Fecha.Value.Year, operacion.Fecha.Value.Month, operacion.Fecha.Value.Day, operacion.Hora.Value.Hour, operacion.Hora.Value.Minute, operacion.Hora.Value.Second);
                    //Estación
                    var estacion = estaciones.Where(e => e.Nombre.Contains(operacion.Parada)).FirstOrDefault();
                    //Cliente
                    var cliente = contexto.Cliente.Where(c => c.Identificacion == operacion.Cliente).FirstOrDefault();


                    if (cliente == null)
                    {
                        cliente = contexto.Cliente.Where(c => c.Tarjeta.codigo == operacion.Cliente).FirstOrDefault();

                    }
                    var bicicleta = contexto.Bicicleta.Where(b => b.Numero == operacion.Bicicleta).FirstOrDefault();

                    //Si cliente y estación existen se crea los registros.
                    if (cliente != null && estacion != null && bicicleta != null)
                    {
                        #region Operacion
                        Operacion operacionBiciq = new Operacion();
                        operacionBiciq.IdCliente = cliente.Id;
                        operacionBiciq.Estado = "ACT";
                        operacionBiciq.Fecha = fecha;
                        operacionBiciq.Id = Guid.NewGuid();
                        operacionBiciq.IdEstacion = estacion.Id;
                        operacionBiciq.IdUsuario = usuario;

                       
                       
                        operacionBiciq.IdTipoOperacion = operacionPrestamo;
                        
                        contexto.Operacion.AddObject(operacionBiciq);
                        #endregion

                        #region Detalle Operacion
                        DetalleOperacion detalle = new DetalleOperacion();
                        detalle.Id = Guid.NewGuid();
                        detalle.IdBicicleta = bicicleta.Id;
                        detalle.IdOperacion = operacionBiciq.Id;

                        contexto.DetalleOperacion.AddObject(detalle);
                        #endregion

                        #region Historia Cliente y Bicicleta
                        
                      
                            HistoriaCliente historiaCliente = new HistoriaCliente();
                            historiaCliente.Estado = "ACT";
                            historiaCliente.Fecha = fecha;
                            historiaCliente.HoraPrestamo = new TimeSpan(fecha.Value.Hour, fecha.Value.Minute, fecha.Value.Second);
                            historiaCliente.Id = Guid.NewGuid();
                            historiaCliente.IdCliente = cliente.Id;
                            historiaCliente.IdEstacionPrestamo = estacion.Id;
                            historiaCliente.IdOperacionPrestamo = operacionBiciq.Id;

                            contexto.HistoriaCliente.AddObject(historiaCliente);

                            HistoriaBicilieta historiaBicicleta = new HistoriaBicilieta();
                            historiaBicicleta.Fecha = fecha;
                            historiaBicicleta.HoraPrestamo = historiaCliente.HoraPrestamo;
                            historiaBicicleta.Id = Guid.NewGuid();
                            historiaBicicleta.IdBicileta = bicicleta.Id;
                            historiaBicicleta.IdCliente = cliente.Id;
                            historiaBicicleta.IdEstacionPrestamo = estacion.Id;
                            historiaBicicleta.IdOperacionPrestamo = operacionBiciq.Id;

                            contexto.HistoriaBicilieta.AddObject(historiaBicicleta);
                    


                        #endregion


                    }

                    totalRegistrosProcesados = totalRegistrosProcesados + 1;
                    System.Diagnostics.Trace.WriteLine("Procesado Registro: " + totalRegistrosProcesados.ToString());

                }
                System.Diagnostics.Trace.WriteLine("Grabando Préstamos.....");
                contexto.SaveChanges();
                #endregion

                #region Devolucion

                System.Diagnostics.Trace.WriteLine("Empezando Devoluciones.....");
                foreach (var operacion in contexto.OperacionesEstacion.Where(o => o.operacion == "devolucion").OrderBy(o => o.Fecha))
                {
                    var fecha = operacion.Fecha = new DateTime(operacion.Fecha.Value.Year, operacion.Fecha.Value.Month, operacion.Fecha.Value.Day, operacion.Hora.Value.Hour, operacion.Hora.Value.Minute, operacion.Hora.Value.Second);
                    //Estación
                    var estacion = estaciones.Where(e => e.Nombre.Contains(operacion.Parada)).FirstOrDefault();
                    //Cliente
                    var cliente = contexto.Cliente.Where(c => c.Identificacion == operacion.Cliente).FirstOrDefault();

                   

                    if (cliente == null)
                    {
                        cliente = contexto.Cliente.Where(c => c.Tarjeta.codigo == operacion.Cliente).FirstOrDefault();

                    }

                    var bicicleta = contexto.Bicicleta.Where(b => b.Numero == operacion.Bicicleta).FirstOrDefault();

                    //Si cliente y estación existen se crea los registros.
                    if (cliente != null && estacion != null && bicicleta != null)
                    {
                        #region Operacion
                        Operacion operacionBiciq = new Operacion();
                        operacionBiciq.IdCliente = cliente.Id;
                        operacionBiciq.Estado = "ACT";
                        operacionBiciq.Fecha = fecha;
                        operacionBiciq.Id = Guid.NewGuid();
                        operacionBiciq.IdEstacion = estacion.Id;
                        operacionBiciq.IdUsuario = usuario;

                      
                            operacionBiciq.IdTipoOperacion = operacionDevolucion;
                            prestamo = contexto.Operacion.Where(o => o.IdCliente == cliente.Id && o.IdTipoOperacion == operacionPrestamo && o.Estado == "ACT"
                               && o.Fecha.Value.Year == operacion.Fecha.Value.Year && o.Fecha.Value.Month == operacion.Fecha.Value.Month
                               && o.Fecha.Value.Day == operacion.Fecha.Value.Day).FirstOrDefault();
                            if (prestamo != null)
                            {

                                operacionBiciq.Estado = "COM";
                                operacionBiciq.IdOperacionFinaliza = prestamo.Id;
                            }
                        
                      
                        contexto.Operacion.AddObject(operacionBiciq);
                        #endregion

                        #region Detalle Operacion
                        DetalleOperacion detalle = new DetalleOperacion();
                        detalle.Id = Guid.NewGuid();
                        detalle.IdBicicleta = bicicleta.Id;
                        detalle.IdOperacion = operacionBiciq.Id;

                        contexto.DetalleOperacion.AddObject(detalle);
                        #endregion

                        #region Historia Cliente y Bicicleta
                       
                            if (prestamo != null)
                            {
                                var historiaCliente = contexto.HistoriaCliente.Where(h => h.IdOperacionPrestamo == prestamo.Id).FirstOrDefault();
                                var historiaBicileta = contexto.HistoriaBicilieta.Where(h => h.IdOperacionPrestamo == prestamo.Id).FirstOrDefault();

                                var parametrosSancion = contexto.ParametrosSanciones.FirstOrDefault();
                                var tiempoParametro = parametrosSancion.TiempoRecorrido;

                                var tiempoRecorrido = DateTime.Now.Subtract(prestamo.Fecha.Value).Minutes;

                                int minutosRetraso = 0;
                                if (tiempoRecorrido > tiempoParametro)
                                {
                                    minutosRetraso = tiempoRecorrido - tiempoParametro.Value;
                                    if (minutosRetraso > parametrosSancion.TiempoLimite)
                                    {
                                        var numeroRetrasos = contexto.HistoriaCliente.Where(h => h.MinutosRetraso > parametrosSancion.TiempoLimite).Count();
                                        switch (numeroRetrasos + 1)
                                        {

                                            case 1:
                                                historiaCliente.TiempoSancion = parametrosSancion.TiempoPrimeraVez;
                                                historiaCliente.TipoTiempoSancion = parametrosSancion.TipoPrimeraVez;
                                                break;
                                            case 2:
                                                historiaCliente.TiempoSancion = parametrosSancion.TiempoSegundaVez;
                                                historiaCliente.TipoTiempoSancion = parametrosSancion.TipoSegundavez;
                                                break;
                                            case 3:
                                                historiaCliente.TiempoSancion = parametrosSancion.TiempoTercerVez;
                                                historiaCliente.TipoTiempoSancion = parametrosSancion.TipoTerceraVez;
                                                break;

                                            case 4:
                                                historiaCliente.TiempoSancion = parametrosSancion.TiempoCuartaVez;
                                                historiaCliente.TipoTiempoSancion = parametrosSancion.TipoCuartaVez;
                                                break;
                                        }

                                    }

                                }
                                historiaBicileta.IdOperacionEntrega = operacionBiciq.Id;
                                historiaBicileta.IdEstacionEntrega = estacion.Id;
                                historiaBicileta.HoraEntrega = new TimeSpan(fecha.Value.Hour, fecha.Value.Minute, fecha.Value.Second);


                                historiaCliente.IdEstacionEntrega = estacion.Id;
                                historiaCliente.IdOperacionEntrega = operacionBiciq.Id;
                                historiaCliente.MinutosRecorrido = tiempoRecorrido;
                                historiaCliente.MinutosRetraso = minutosRetraso;
                            }
                       


                        #endregion


                    }

                    totalRegistrosProcesados = totalRegistrosProcesados + 1;
                    System.Diagnostics.Trace.WriteLine("Procesado Registro: " + totalRegistrosProcesados.ToString());

                }
                #endregion

                System.Diagnostics.Trace.WriteLine("Grabando Devoluciones.....");
                contexto.SaveChanges();
                System.Diagnostics.Trace.WriteLine("FIN");
            }


            return resultado;
        }


        public Resultado CuadrarInformacion()
        {
            Resultado resultado = new Resultado();
            using (var contexto = new ContextoBiciq())
            {
                System.Diagnostics.Trace.WriteLine("Empezando Préstamos.....");
                foreach (var operacion in contexto.Operacion.Where(o => o.IdTipoOperacion == operacionPrestamo && o.IdOperacionFinaliza == null))
                {

                }

            }

            return resultado;
        }
    }
}
